package com.cirkana.viewer.data.security;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.cirkana.data.IDataColumnDef;
import com.cirkana.data.IDataTableDef;
import com.cirkana.data.security.IUser;
import com.cirkana.data.security.IUserService;
import com.cirkana.serial.bin.BinarySerializationException;
import com.cirkana.serial.bin.BinarySerializationUtil;
import com.cirkana.serial.text.TextSerializationBuilder;
import com.cirkana.viewer.data.DataColumnDef;
import com.cirkana.viewer.data.LocalDataRecord;

public class User extends LocalDataRecord implements IUser {

	protected static final String COLUMN_USER_ID = "USER_ID";
	protected static final String COLUMN_NICK_NAME = "NICK_NAME";
	protected static final String COLUMN_PASSWORD = "PASSWORD";
	protected static final String COLUMN_NAME = "NAME";
	protected static final String COLUMN_MIDDLE_NAME = "MIDDLE_NAME";
	protected static final String COLUMN_LAST_NAME = "LAST_NAME";
	protected static final String COLUMN_EMAIL = "EMAIL";
	protected static final String COLUMN_BIRTH_DATE = "BIRTH_DATE";
	protected static final String COLUMN_CITY = "CITY";
	protected static final String COLUMN_COUNTRY = "COUNTRY";
	protected static final String COLUMN_LANGUAGE = "LANGUAGE";
	protected static final String COLUMN_AVATAR_SUMMARY = "AVATAR_SUMMARY";
	protected static final String COLUMN_AVATAR_PIC_ID = "AVATAR_PIC_ID";
	protected static final String OBJECT_USER_SERVICES = "OBJECT_USER_SERVICES";

	public static final IDataTableDef tableDef = new UserTableDef();

	@Override
	public Integer getId() {
		return getIntegerField(COLUMN_USER_ID);
	}

	@Override
	public void setId(Integer id) {
		setIntegerField(COLUMN_USER_ID, id);
	}

	@Override
	public Integer getAvatarPicId() {
		return getIntegerField(COLUMN_AVATAR_PIC_ID);
	}

	@Override
	public String getAvatarSummary() {
		return getStringField(COLUMN_AVATAR_SUMMARY);
	}

	@Override
	public Date getBirthDate() {
		return getDateField(COLUMN_BIRTH_DATE);
	}

	@Override
	public String getCity() {
		return getStringField(COLUMN_CITY);
	}

	@Override
	public String getCountry() {
		return getStringField(COLUMN_COUNTRY);
	}

	@Override
	public String getEmail() {
		return getStringField(COLUMN_EMAIL);
	}

	@Override
	public String getLanguage() {
		return getStringField(COLUMN_LANGUAGE);
	}

	@Override
	public String getLastName() {
		return getStringField(COLUMN_LAST_NAME);
	}

	@Override
	public String getMiddleName() {
		return getStringField(COLUMN_MIDDLE_NAME);
	}

	@Override
	public String getName() {
		return getStringField(COLUMN_NAME);
	}

	@Override
	public String getNickName() {
		return getStringField(COLUMN_NICK_NAME);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, IUserService> getUserServices() {
		return (Map<String, IUserService>) getField(OBJECT_USER_SERVICES);
	};

	@Override
	public void setAvatarPicId(Integer avatarPicId) {
		setField(COLUMN_AVATAR_PIC_ID, avatarPicId);
	}

	@Override
	public void setAvatarSummary(String avatarSummary) {
		setStringField(COLUMN_AVATAR_SUMMARY, avatarSummary);
	}

	@Override
	public void setBirthDate(Date birthDate) {
		setDateField(COLUMN_BIRTH_DATE, birthDate);
	}

	@Override
	public void setCity(String city) {
		setStringField(COLUMN_CITY, city);
	}

	@Override
	public void setCountry(String country) {
		setStringField(COLUMN_COUNTRY, country);
	}

	@Override
	public void setEmail(String email) {
		setStringField(COLUMN_EMAIL, email);
	}

	@Override
	public void setLanguage(String language) {
		setStringField(COLUMN_LANGUAGE, language);
	}

	@Override
	public void setLastName(String lastName) {
		setStringField(COLUMN_LAST_NAME, lastName);
	}

	@Override
	public void setMiddleName(String middleName) {
		setStringField(COLUMN_MIDDLE_NAME, middleName);
	}

	@Override
	public void setName(String name) {
		setStringField(COLUMN_NAME, name);
	}

	@Override
	public void setNickName(String nickName) {
		setStringField(COLUMN_NICK_NAME, nickName);
	}

	@Override
	public void setUserServices(Map<String, IUserService> userServices) {
		setField(OBJECT_USER_SERVICES, userServices);
	}

	@Override
	public String getPassword() {
		return getStringField(COLUMN_PASSWORD);
	}

	@Override
	public void setPassword(String password) {
		setStringField(COLUMN_PASSWORD, password);
	}

	@Override
	public void serialize(DataOutputStream out) throws BinarySerializationException {
		BinarySerializationUtil.serializeInteger(getId(), out);
		BinarySerializationUtil.serializeString(getNickName(), out);
		BinarySerializationUtil.serializeString(getPassword(), out);
		BinarySerializationUtil.serializeString(getName(), out);
		BinarySerializationUtil.serializeString(getMiddleName(), out);
		BinarySerializationUtil.serializeString(getLastName(), out);
		BinarySerializationUtil.serializeString(getEmail(), out);
		BinarySerializationUtil.serializeDate(getBirthDate(), out);
		BinarySerializationUtil.serializeString(getCity(), out);
		BinarySerializationUtil.serializeString(getCountry(), out);
		BinarySerializationUtil.serializeString(getLanguage(), out);
		BinarySerializationUtil.serializeInteger(getAvatarPicId(), out);
		BinarySerializationUtil.serializeString(getAvatarSummary(), out);
		BinarySerializationUtil.serializeSerializableMap(getUserServices(), out);
	}

	@SuppressWarnings("unchecked")
	@Override
	public void deserialize(DataInputStream in) throws BinarySerializationException {
		setId(BinarySerializationUtil.deserializeInteger(in));
		setNickName(BinarySerializationUtil.deserializeString(in));
		setPassword(BinarySerializationUtil.deserializeString(in));
		setName(BinarySerializationUtil.deserializeString(in));
		setMiddleName(BinarySerializationUtil.deserializeString(in));
		setLastName(BinarySerializationUtil.deserializeString(in));
		setEmail(BinarySerializationUtil.deserializeString(in));
		setBirthDate(BinarySerializationUtil.deserializeDate(in));
		setCity(BinarySerializationUtil.deserializeString(in));
		setCountry(BinarySerializationUtil.deserializeString(in));
		setLanguage(BinarySerializationUtil.deserializeString(in));
		setAvatarPicId(BinarySerializationUtil.deserializeInteger(in));
		setAvatarSummary(BinarySerializationUtil.deserializeString(in));
		setUserServices((Map<String, IUserService>) BinarySerializationUtil.deserializeSerializableMap(UserService.class, in));
	}

	@Override
	public String toText() {
		TextSerializationBuilder t = new TextSerializationBuilder();
		t.append("id", getId());
		t.append("nickName", getNickName());
		t.append("password", getPassword());
		t.append("name", getName());
		t.append("middleName", getMiddleName());
		t.append("lastName", getLastName());
		t.append("email", getEmail());
		t.append("birthDate", getBirthDate());
		t.append("city", getCity());
		t.append("country", getCountry());
		t.append("language", getLanguage());
		t.append("avatarPicId", getAvatarPicId());
		t.append("avatarSummary", getAvatarSummary());
		t.append("userServices", getUserServices());
		return t.getTextSerialization();
	}

	static class UserTableDef implements IDataTableDef {

		private static final String TABLE_NAME = "USERS";
		private static final List<IDataColumnDef> TABLE_COLUMNS = new ArrayList<IDataColumnDef>();
		static {
			TABLE_COLUMNS.add(new DataColumnDef(0, COLUMN_USER_ID, int.class, true, true));
			TABLE_COLUMNS.add(new DataColumnDef(1, COLUMN_NICK_NAME, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(2, COLUMN_PASSWORD, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(3, COLUMN_NAME, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(4, COLUMN_MIDDLE_NAME, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(5, COLUMN_LAST_NAME, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(6, COLUMN_EMAIL, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(7, COLUMN_BIRTH_DATE, Date.class));
			TABLE_COLUMNS.add(new DataColumnDef(8, COLUMN_CITY, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(9, COLUMN_COUNTRY, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(10, COLUMN_LANGUAGE, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(11, COLUMN_AVATAR_SUMMARY, String.class));
			TABLE_COLUMNS.add(new DataColumnDef(12, COLUMN_AVATAR_PIC_ID, int.class));
		}

		@Override
		public String getTableName() {
			return TABLE_NAME;
		}

		@Override
		public List<IDataColumnDef> getColumnsDef() {
			return TABLE_COLUMNS;
		}

		@Override
		public Class<?> getDataRecordType() {
			return User.class;
		}

	}
}
